package com.jt.aspect;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.annotation.RequiredLog;
import com.jt.pojo.Logger;
import com.jt.service.LogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Component
public class LogAspect {

    @Pointcut("@annotation(com.jt.annotation.RequiredLog)")
    public void doLog(){}


    @Around("doLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        int status =1;
        String error = null;
        Long time =0L;
        long t1 =System.currentTimeMillis();
        try {
            Object proceed = joinPoint.proceed();
            long t2 = System.currentTimeMillis();
            time = t2-t1;
            return proceed;
        }catch (Throwable e){
            long t3 =System.currentTimeMillis();
            time =t3-t1;
            error= e.getMessage();
            status =0;
            throw  e;
        }finally {
            saveLog(joinPoint,time,status,error);
        }

    }

    private void saveLog(ProceedingJoinPoint joinPoint, Long time, int status, String error) throws NoSuchMethodException, JsonProcessingException {
        Class<?> aClass = joinPoint.getTarget().getClass();
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method declaredMethod = aClass.getDeclaredMethod(signature.getName(), signature.getParameterTypes());
        RequiredLog annotation = declaredMethod.getAnnotation(RequiredLog.class);
        String operation = annotation.value();
        String targetMethod=aClass.getName()+"."+ declaredMethod.getName();
        String params = new ObjectMapper().writeValueAsString(joinPoint.getArgs());
        String username =(String) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
       ServletRequestAttributes requestAttributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String Ip = requestAttributes.getRequest().getRemoteAddr();
        Logger logInfo = new Logger();
        logInfo.setIp(Ip);
        logInfo.setUsername(username);
        logInfo.setOperation(operation);
        logInfo.setMethod(targetMethod);
        logInfo.setParams(params);
        logInfo.setTime(time);
        logInfo.setStatus(status);
        logInfo.setError(error);
        logInfo.setCreatedTime(new Date());
        System.out.println("logInfo ="+logInfo);
        logService.doInsertLog(logInfo);
    }
    @Autowired
    private LogService logService;


}
